using UnityEngine;

public  enum ElementType{ None, Fire, Ice, Lightning }
public class Entity_Stat : MonoBehaviour
{
    [SerializeField] private StatSetupDataSO setup;
    public Stat_ResourceGroup resources;
    public Stat_MajorGroup major; //主属性
    public Stat_DefenseGroup defense; //防御
    public Stat_OffensiveGroup offense; //攻击

    protected virtual void Awake()
    {
        
    }

    public void AdjustStatSetup(Entity_Stat stat, float penalty, float increase)
    {
        Stat_DefenseGroup defenseGroup = stat.defense;
        Stat_ResourceGroup resourceGroup = stat.resources;
        Stat_OffensiveGroup offensiveGroup = stat.offense;

        offense.damage.SetBaseValue(offensiveGroup.damage.GetValue() * increase);
        offense.attackSpeed.SetBaseValue(offensiveGroup.attackSpeed.GetValue() * increase);
        offense.critChance.SetBaseValue(offensiveGroup.critChance.GetValue() * increase);
        offense.critPower.SetBaseValue(offensiveGroup.critPower.GetValue() * increase);
        offense.fireDamage.SetBaseValue(offensiveGroup.fireDamage.GetValue() * increase);
        offense.iceDamage.SetBaseValue(offensiveGroup.iceDamage.GetValue() * increase);
        offense.lightningDamage.SetBaseValue(offensiveGroup.attackSpeed.GetValue() * increase);

        defense.evasion.SetBaseValue(defenseGroup.evasion.GetValue() * increase);

        resources.maxHealth.SetBaseValue(resourceGroup.maxHealth.GetValue() * penalty);
        resources.healthRegen.SetBaseValue(resourceGroup.healthRegen.GetValue() * penalty);

        defense.armor.SetBaseValue(defenseGroup.armor.GetValue() * penalty);
        defense.lightningRes.SetBaseValue(defenseGroup.lightningRes.GetValue() * penalty);
        defense.fireRes.SetBaseValue(defenseGroup.fireRes.GetValue() * penalty);
        defense.iceRes.SetBaseValue(defenseGroup.iceRes.GetValue() * penalty);

    }

    public AttackData GetAttackData(DamageScaleData damageScaleData)
    {
        return new AttackData(this, damageScaleData);
    }

    /// <summary>
    /// 计算最大生命值
    /// 返回最大生命值
    /// </summary>
    /// <returns></returns>
    public float GetMaxHealth()
    {
        float baseHp = resources.maxHealth.GetValue();
        float bonusHp = major.vitality.GetValue() * 5f;
        float finalHealth = baseHp + bonusHp;
        return finalHealth;
    }

    /// <summary>
    /// 计算闪避值
    /// 返回闪避值
    /// </summary>
    /// <returns></returns>
    public float GetEvasion()
    {
        float baseEvasion = defense.evasion.GetValue();
        float bonusEvasion = major.agility.GetValue() * .5f; //每幸运+0.5闪避
        float totalEvasion = baseEvasion + bonusEvasion;
        float evasionCap = 70f;
        float finalEvasion = Mathf.Clamp(totalEvasion, 0, evasionCap);
        return finalEvasion;
    }

    /// <summary>
    /// 计算物理伤害
    /// 返回物理伤害
    /// </summary>
    /// <param name="isCrit"></param>
    /// <returns></returns>
    public float GetPhysicalDamage(out bool isCrit, float scaleFactor = 1)
    {
        float baseDamage = GetBaseDamage();

        float critChance = GetCritChance();

        //将暴击伤害除以100变成基础伤害的倍数（180 / 100= 1.8f）
        float critPower = GetCritPower() / 100;

        
        isCrit = Random.Range(0, 100) < critChance;
        float finalDamage = isCrit ? baseDamage * critPower : baseDamage;
        return finalDamage * scaleFactor;
    }

    //基础伤害 = 伤害 + 力量
    public float GetBaseDamage() => offense.damage.GetValue() + major.strength.GetValue(); 

    //暴击率 = 暴击率 + 每幸运+0.3%暴击率
    public float GetCritChance() => offense.critChance.GetValue() + major.agility.GetValue() * .3f;

    //暴击伤害=暴击伤害 + 每力量+0.5%暴击伤害
    public float GetCritPower() => offense.critPower.GetValue() + major.strength.GetValue() * .5f;


    /// <summary>
    /// 计算防御系数
    /// 总计防御=（基础防御+每幸运所增加的防御）*破甲系数
    /// 防御系数=（总计防御）/（总计防御+100）
    /// 限制防御系数范围（0，0.85）
    /// </summary>
    /// <returns></returns>
    public float GetArmorMitigation(float armorReduction)
    {
        float baseArmor = GetBaseArmor();
        float reductionMutliplier = Mathf.Clamp(1 - armorReduction, 0, 1);
        float effectiveArmor = baseArmor * reductionMutliplier;
        float mitigation = effectiveArmor / (effectiveArmor + 100); //计算防御系数
        float mitigationCap = .85f;
        float finalMitigation = Mathf.Clamp(mitigation, 0, mitigationCap);
        return finalMitigation;
    }

    //基础防御=防御+每活力+1防御
    public float GetBaseArmor() => defense.armor.GetValue() + major.vitality.GetValue();

    public float GetArmorReduction()
    {
        float finalArmorReducion = offense.armorReduction.GetValue() / 100;
        return finalArmorReducion;
    }

    /// <summary>
    /// 计算元素伤害
    /// 计算：总元素伤害值 = 元素伤害为最强元素伤害值 + 衰减后的弱元素伤害值 + 每智力所增加的元素伤害
    /// </summary>
    /// <returns></returns>
    public float GetElementalDamage(out ElementType elementialType, float scaleFactor)
    {

        float fireDamage = offense.fireDamage.GetValue();
        float iceDamage = offense.iceDamage.GetValue();
        float lightningDamage = offense.lightningDamage.GetValue();
        float bonusElementalDamage = major.intelligence.GetValue(); //每智力+1元素伤害
        float highestDamage = fireDamage;
        elementialType = ElementType.Fire;
        //判断最高的元素伤害为主元素伤害
        if (iceDamage > highestDamage)
        {
            elementialType = ElementType.Ice;
            highestDamage = iceDamage;
        }
        if (lightningDamage > highestDamage)
        {
            elementialType = ElementType.Lightning;
            highestDamage = lightningDamage;
        }
        if (highestDamage <= 0)
            return 0;
        //判断非主元素伤害，非主元素伤害衰减50%后叠加到总元素伤害
        float bonusFireDamage = (fireDamage == highestDamage) ? 0 : fireDamage * .5f;
        float bonusIceDamage = (iceDamage == highestDamage) ? 0 : iceDamage * .5f;
        float bonusLightningDamage = (lightningDamage == highestDamage) ? 0 : lightningDamage * .5f;
        float weakerElementsDamage = bonusFireDamage + bonusIceDamage + bonusLightningDamage;
        //总元素伤害=强元素伤害+衰减后的弱元素伤害+每智力所增加的元素伤害
        float finalDamage = highestDamage + weakerElementsDamage + bonusElementalDamage;
        return finalDamage * scaleFactor;
    }

    public float GetElementalResistance(ElementType elementType)
    {
        float baseResistance = 0;
        float bonusResistance = major.intelligence.GetValue() * .5f; //每智力+0.5%的法抗
        switch (elementType)
        {
            case ElementType.Fire:
                baseResistance = defense.fireRes.GetValue();
                break;
            case ElementType.Ice:
                baseResistance = defense.iceRes.GetValue();
                break;
            case ElementType.Lightning:
                baseResistance = defense.lightningRes.GetValue();
                break;
            default:
                break;
        }
        float resistance = baseResistance + bonusResistance;
        float resistanceCap = 75f;
        float finalResistance = Mathf.Clamp(resistance, 0, resistanceCap) / 100;
        return finalResistance;
    }
    public Stat GetStatByType(StatType type)
    {
        return type switch
        {
            StatType.MaxHealth => resources.maxHealth,
            StatType.HealthRegen => resources.healthRegen,

            StatType.Strength => major.strength,
            StatType.Agility => major.agility,
            StatType.Intelligence => major.intelligence,
            StatType.Vitality => major.vitality,

            StatType.Armor => defense.armor,
            StatType.Evasion => defense.evasion,
            StatType.FireResistance => defense.fireRes,
            StatType.IceResistance => defense.iceRes,
            StatType.LightningResistance => defense.lightningRes,

            StatType.ArmorReduction => offense.armorReduction,
            StatType.AttackSpeed => offense.attackSpeed,
            StatType.CritChance => offense.critChance,
            StatType.CritPower => offense.critPower,
            StatType.IceDamage => offense.iceDamage,
            StatType.FireDamage => offense.fireDamage,
            StatType.LightningDamage => offense.lightningDamage,
            StatType.Damage => offense.damage,
            _ => null,
        };
    }
    public void AppayDefaultStatSetup()
    {
        if (setup == null)
            return;
        resources.maxHealth.SetBaseValue(setup.maxHealth);
        resources.healthRegen.SetBaseValue(setup.healthRegen);

        major.strength.SetBaseValue(setup.strength);
        major.agility.SetBaseValue(setup.agility);
        major.intelligence.SetBaseValue(setup.intelligence);
        major.vitality.SetBaseValue(setup.vitality);

        offense.attackSpeed.SetBaseValue(setup.attackSpeed);
        offense.damage.SetBaseValue(setup.damage);
        offense.critChance.SetBaseValue(setup.critChance);
        offense.critPower.SetBaseValue(setup.critPower);
        offense.armorReduction.SetBaseValue(setup.armorReduction);

        offense.iceDamage.SetBaseValue(setup.iceDamage);
        offense.fireDamage.SetBaseValue(setup.fireDamage);
        offense.lightningDamage.SetBaseValue(setup.lightningDamage);

        defense.armor.SetBaseValue(setup.armor);
        defense.evasion.SetBaseValue(setup.evasion);

        defense.iceRes.SetBaseValue(setup.IceResistance);
        defense.fireRes.SetBaseValue(setup.FireResistance);
        defense.lightningRes.SetBaseValue(setup.LightningResistance);
    }
}
